package com.mtsmda.collection;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
import java.util.Vector;

public class ListDemo {

	public static void main(String[] args) {
		vectorDemo();
		System.out.println("\n ----- \n");
		stackDemo();
		System.out.println("\n ----- \n");
		arrayListDemo();
		System.out.println("\n ----- \n");
		linkedListDemo();
	}

	/**
	 * <p>
	 * The Vector class implements a growable array of objects. Like an array,
	 * it contains components that can be accessed using an integer index.
	 * However, the size of a Vector can grow or shrink as needed to accommodate
	 * adding and removing items after the Vector has been created.
	 * </p>
	 * 
	 * */
	private static void vectorDemo() {
		List<String> vector = new Vector<>();
		System.out.println(vector.add("Ivan"));
		System.out.println(vector.add("dan"));
		System.out.println(vector.add("Dan"));
		System.out.println(vector.add(null));
		System.out.println(vector.add("Magomed"));
		System.out.println(vector.add("Dan"));
		System.out.println(vector.add("magomed"));
		System.out.println();
		for (String s : vector) {
			if (s == null) {
				continue;
			}
			System.out.println(s);
		}
		System.out.println(vector.size());
	}

	/**
	 * <p>
	 * The Stack class represents a last-in-first-out (LIFO) stack of objects.
	 * It extends class Vector with five operations that allow a vector to be
	 * treated as a stack. The usual push and pop operations are provided, as
	 * well as a method to peek at the top item on the stack, a method to test
	 * for whether the stack is empty, and a method to search the stack for an
	 * item and discover how far it is from the top. When a stack is first
	 * created, it contains no items.
	 * 
	 * A more complete and consistent set of LIFO stack operations is provided
	 * by the Deque interface and its implementations, which should be used in
	 * preference to this class.
	 * </p>
	 * */
	private static void stackDemo() {
		List<String> stack = new Stack<>();
		System.out.println(stack.add("Ivanov"));
		System.out.println(stack.add("Volkov"));
		System.out.println(stack.add(null));
		System.out.println(stack.add("Ivanov"));
		System.out.println(stack.add("Petrov"));
		System.out.println(stack.add("ivanov"));

		for (String s : stack) {
			if (s == null) {
				continue;
			}
			System.out.println(s);
		}
		System.out.println(stack.size());
	}

	/**
	 * <p>
	 * Resizable-array implementation of the List interface. Implements all
	 * optional list operations, and permits all elements, including null. In
	 * addition to implementing the List interface, this class provides methods
	 * to manipulate the size of the array that is used internally to store the
	 * list. (This class is roughly equivalent to Vector, except that it is
	 * unsynchronized.) The size, isEmpty, get, set, iterator, and listIterator
	 * operations run in constant time. The add operation runs in amortized
	 * constant time, that is, adding n elements requires O(n) time. All of the
	 * other operations run in linear time (roughly speaking). The constant
	 * factor is low compared to that for the LinkedList implementation.
	 * 
	 * Each ArrayList instance has a capacity. The capacity is the size of the
	 * array used to store the elements in the list. It is always at least as
	 * large as the list size. As elements are added to an ArrayList, its
	 * capacity grows automatically. The details of the growth policy are not
	 * specified beyond the fact that adding an element has constant amortized
	 * time cost.
	 * 
	 * An application can increase the capacity of an ArrayList instance before
	 * adding a large number of elements using the ensureCapacity operation.
	 * This may reduce the amount of incremental reallocation.
	 * </p>
	 * <hr/>
	 * <p>
	 * ArrayList, which is usually the better-performing implementation
	 * </p>
	 * */
	private static void arrayListDemo() {
		List<String> arrayList = new ArrayList<>();
		System.out.println(arrayList.add("Mazda"));
		System.out.println(arrayList.add("vaz"));
		System.out.println(arrayList.add(null));

		System.out.println(arrayList.contains(null));
		System.out.println(arrayList.add("Mazda"));
		System.out.println(arrayList.add("Opel"));
		System.out.println(arrayList.add("Ferrari"));
		System.out.println(arrayList.add("mazda"));

		for (String s : arrayList) {
			if (s == null) {
				continue;
			}
			System.out.println(s);
		}
		System.out.println(arrayList.size());
	}

	/**
	 * <p>
	 * Doubly-linked list implementation of the List and Deque interfaces.
	 * Implements all optional list operations, and permits all elements
	 * (including null). All of the operations perform as could be expected for
	 * a doubly-linked list. Operations that index into the list will traverse
	 * the list from the beginning or the end, whichever is closer to the
	 * specified index.
	 * </p>
	 * <hr/>
	 * <p>
	 * LinkedList which offers better performance under certain circumstances
	 * </p>
	 * 
	 * */
	private static void linkedListDemo() {
		List<String> linkedList = new LinkedList<>();
		System.out.println(linkedList.add(null));
		System.out.println(linkedList.add("Microsoft"));
		System.out.println(linkedList.add("Oracle"));
		System.out.println(linkedList.add("PHP"));
		System.out.println(linkedList.add("Apple"));

		System.out.println(linkedList.contains(null));
		for (String s : linkedList) {
			if (s == null) {
				continue;
			}
			System.out.println(s);
		}
		System.out.println(linkedList.size());
	}

}
// <p></p>